home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Magnum One
/
Magnum One (Mid-American Digital) (Disc Manufacturing).iso
/
d12
/
cgazv5n5.arc
/
XMSUMB.C
< prev
Wrap
C/C++ Source or Header
|
1991-09-23
|
6KB
|
206 lines
/*--- XMSUMB.C --------------------------- Listing 3 ------
* XMS UMB Functions. main() displays UMB's in use.
* Must be linked to xmsgen (Listing 1)
*
* by David Babcock
*
* Validated for Microsoft and Borland C/C++
*
* (c) 1991 C Gazette. Object Code may be used freely,
* source code may be used if authorship and publication
* are acknowledged.
*-------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <dos.h>
#include "xms.h"
struct UMB
{
unsigned int segment ;
unsigned int paragraphs ;
} ;
/* This structure must be packed: don't let the compiler pad it.
* For MSC, this means that #pragma pack(1) is needed */
#if !defined(__TURBOC__)
#pragma pack(1) /* no packing */
#endif
struct MCB
{
unsigned char signature ;
unsigned int owner ;
unsigned int size ;
} ;
#if !defined(__TURBOC__)
#pragma pack() /* default packing */
#endif
static struct UMB umb [ 16 ] ;
static int umbs = 0 ;
#if 0
/* This code is never to be used, but is left behind
* as a reminder not to implement something else like
* it. See text for details.
*/
void closeUMBs ( void )
{
int i ;
for ( i = 0 ; i < umbs ; ++i )
ReleaseUpperMemoryBlock ( umb [ i ].segment ) ;
}
#endif
int comp ( const void *a, const void *b )
{
register unsigned int au,bu ;
au = ((struct UMB*)a)->segment ;
bu = ((struct UMB*)b)->segment ;
return ( au < bu ? -1 : ( au > bu ) ) ;
}
void main ( void )
{
int i ;
unsigned paragraphs;
struct MCB far *mcbPtr ;
struct MCB far *mcbPtrZ ;
union REGS regs ;
struct SREGS sregs ;
unsigned int ver ;
int firstUMB ;
ver = ( unsigned int ) GetXMSVersionNumber() ;
printf ( "XMS version %s\n", PrintXMSVersionNumber ( ver ));
if ( ver >= 0x200 )
{
/* scarf up all available UMBs */
#if 0 /* never used - see text */
atexit ( closeUMBs ) ;
#endif
for ( firstUMB = 1 ; ; firstUMB = 0 )
{
RequestUpperMemoryBlock ( 0xFFFF ) ;
if ( firstUMB )
printf ( "Largest free upper memory block:\n" );
printf ( "%xh paragraphs\n", xms_struc.ret_dx );
if ( xms_struc.ret_dx > 0 )
{
RequestUpperMemoryBlock ( xms_struc.ret_dx ) ;
umb [ umbs ].segment = xms_struc.ret_bx ;
umb [ umbs++ ].paragraphs = xms_struc.ret_dx ;
}
else break ;
}
/* sort the UMBs by address */
qsort ( umb, umbs, sizeof ( umb[0] ), comp ) ;
/* insert the UMBs in the DOS allocation chain */
/* get the base of the chain */
regs.h.ah = 0x52 ;
intdosx ( ®s, ®s, &sregs ) ;
mcbPtr = MK_FP ( sregs.es, regs.x.bx - 2 ) ;
/* get the last link: its signature is 'Z' */
mcbPtr = MK_FP ( *((unsigned far*)mcbPtr), 0 ) ;
for ( ;; )
{
if ( mcbPtr->signature == 'Z' )
{
mcbPtrZ = mcbPtr ;
break ;
}
mcbPtr = MK_FP ( FP_SEG(mcbPtr) +
mcbPtr->size + 1, 0 ) ;
}
printf ( "\n\nUMBs:\nsegment\t\tparagraphs\n\n" ) ;
paragraphs = 0;
for ( i = 0 ; i < umbs ; ++i )
{
printf ( "%04x\t\t%04xh\n",
umb [ i ].segment, umb [ i ].paragraphs ) ;
paragraphs += umb [ i ].paragraphs;
}
if ( umbs > 0 )
{
printf("\n\nCan add to allocation chain."
" Will add a total of %u bytes.",
paragraphs * 16);
/* In each memory block, set aside the first and
last paragraphs for MCBs. Make DOS the owner of the
first, and a dummy process the owner of the last. */
for ( i = 0 ; i < umbs - 1 ; ++i )
{
mcbPtr = MK_FP ( umb [ i ].segment, 0 ) ;
mcbPtr->signature = 'M' ;
mcbPtr->owner = 0 ;
mcbPtr->size = umb [ i ].paragraphs - 2 ;
mcbPtr = MK_FP ( umb [ i ].segment
+ umb [ i ].paragraphs - 1, 0 ) ;
mcbPtr->signature = 'M' ;
mcbPtr->owner = 0xFFFF ;
mcbPtr->size = umb [ i + 1 ].segment
- FP_SEG ( mcbPtr ) - 1 ;
}
mcbPtr = MK_FP ( umb [ i ].segment, 0 ) ;
mcbPtr->signature = 'Z' ;
mcbPtr->owner = 0 ;
mcbPtr->size = umb [ i ].paragraphs - 1 ;
/* modify the last DOS block to add the
new blocks to the chain */
mcbPtrZ->signature = 'M' ;
mcbPtr = MK_FP ( FP_SEG(mcbPtrZ) +
mcbPtrZ->size--, 0 ) ;
mcbPtr->signature = 'M' ;
mcbPtr->owner = 0xFFFF ;
mcbPtr->size = umb [ 0 ].segment -
FP_SEG ( mcbPtr ) - 1 ;
regs.h.ah = 0x52 ;
intdosx ( ®s, ®s, &sregs ) ;
mcbPtr = MK_FP ( sregs.es, regs.x.bx - 2 ) ;
/* get the last link: its signature is 'Z' */
mcbPtr = MK_FP ( *((unsigned far*)mcbPtr), 0 ) ;
/* display the allocation chain */
printf ( "\n\n\nAllocation chain links:\n" ) ;
printf ( "M/Z\t\tsegment\t\towner\t\tsize\n\n" ) ;
for ( ;; )
{
printf ( "%c\t\t%04x\t\t%04x\t\t%4xh\n",
mcbPtr->signature, FP_SEG(mcbPtr),
mcbPtr->owner, mcbPtr->size ) ;
if ( mcbPtr->signature == 'Z' )
{
mcbPtrZ = mcbPtr ;
break ;
}
mcbPtr = MK_FP ( FP_SEG(mcbPtr) +
mcbPtr->size + 1, 0 ) ;
}
}
}
}